package ar.frba.utn.diseñosistemas.TP2;

import java.util.ArrayList;
import java.util.List;

import com.oceanic.AerolineaOceanic;
import com.oceanic.AsientoDTO;

public class OceanicAdapter extends Aerolinea 
{
	private AerolineaOceanic oceanic;
	
	public OceanicAdapter()
	{
		this.porcentajeImpuesto = 0;
		oceanic = AerolineaOceanic.getInstance();
	}
	
	@Override
	public void comprar(Asiento unAsiento, Usuario unUsuario) 
	{
		Boolean pudoComprar = this.oceanic.comprarSiHayDisponibilidad(unUsuario.getDNI(), unAsiento.getCodigoVuelo(), Integer.parseInt(unAsiento.getNumeroAsiento()));
		if(!pudoComprar)
			throw new RuntimeException("El asiento no pudo ser comprado");
		
		unAsiento.setEstado(EstadoAsiento.Comprado);
	}

	@Override
	public ArrayList<Asiento> buscar(Busqueda unaBusqueda) 
	{
		ArrayList<Asiento> resultado = new ArrayList<Asiento>();
		String origen = this.parseCiudad(unaBusqueda.getOrigen());
		String destino = this.parseCiudad(unaBusqueda.getDestino());
		
		List<AsientoDTO> asientos = oceanic.asientosDisponiblesParaOrigenYDestino(origen, destino, unaBusqueda.getFecha());
		
		for (AsientoDTO unAsiento : asientos) 
		{
			Asiento asiento = this.parseAsiento(unAsiento);
			this.aplicarImpuestoA(asiento);
			
			resultado.add(asiento);
		}
		
		return resultado;
	}
	
	@Override
	public ArrayList<Asiento> buscarSinDestino(Busqueda unaBusqueda) 
	{
		ArrayList<Asiento> resultado = new ArrayList<Asiento>();
		String origen = this.parseCiudad(unaBusqueda.getOrigen());
		
		List<AsientoDTO> asientos = oceanic.asientosDisponiblesParaOrigen(origen, unaBusqueda.getFecha());
		
		for (AsientoDTO unAsiento : asientos) 
		{
			Asiento asiento = this.parseAsiento(unAsiento);
			this.aplicarImpuestoA(asiento);
			
			resultado.add(asiento);
		}
		
		return resultado;
	}

	public void reservar(Asiento unAsiento, Usuario unUsuario)
	{
		Boolean pudoReservar = this.oceanic.reservar(unUsuario.getDNI(), unAsiento.getCodigoVuelo(), Integer.parseInt(unAsiento.getNumeroAsiento()));
		if (!pudoReservar)
			throw new RuntimeException("No se pudo efectuar la reserva");
		
		unAsiento.setEstado(EstadoAsiento.Reservado);
	}

	public Boolean estaReservado(Asiento unAsiento)
	{
		return this.oceanic.estaReservado(unAsiento.getCodigoVuelo(), Integer.parseInt(unAsiento.getNumeroAsiento()));
	}
	
	private Asiento parseAsiento(AsientoDTO unAsiento)
	{
		Ubicacion ubicacion = this.parseUbicacion(unAsiento.getUbicacion());
		Clase clase = this.parseClase(unAsiento.getClase());
		EstadoAsiento estado = (unAsiento.getReservado()) ? EstadoAsiento.Reservado : EstadoAsiento.Disponible; 
		
		return new Asiento(unAsiento.getCodigoDeVuelo(), Integer.toString(unAsiento.getNumeroDeAsiento())
						 , unAsiento.getPrecio().floatValue(), clase, ubicacion, estado
						 , unAsiento.getFechaDeSalida(), unAsiento.getHoraDeSalida()
						 , unAsiento.getFechaDeLlegada(), unAsiento.getHoraDeLlegada()
						 , this, unAsiento.getOrigen(), unAsiento.getDestino());
	}

	private Ubicacion parseUbicacion(String ubicacion) 
	{
		if (ubicacion.equalsIgnoreCase("Centro"))
			return Ubicacion.Centro;
		if (ubicacion.equalsIgnoreCase("Pasillo"))
			return Ubicacion.Pasillo;
		if (ubicacion.equalsIgnoreCase("Ventana"))
			return Ubicacion.Ventanilla;
		
		throw new RuntimeException("El servicio devolvio una ubicacion invalida: " + ubicacion);
	}

	private Clase parseClase(String clase) 
	{		
		if (clase.equalsIgnoreCase("Turista"))
			return Clase.Turista;
		if (clase.equalsIgnoreCase("Ejecutiva"))
			return Clase.Ejecutivo;
		if (clase.equalsIgnoreCase("Primera"))
			return Clase.Primera;
		
		throw new RuntimeException("El servicio devolvio una clase invalida: " + clase);
	}
	
	private String parseCiudad(String ciudad)
	{
		if (ciudad.compareToIgnoreCase("LA") == 0)
			return "SLA";
		
		return (ciudad.length() < 3) ? "_" + ciudad : ciudad;
	}

	void cambiarEstadoAsientoADisponible(Asiento asiento) 
	{
		asiento.setEstado(EstadoAsiento.Disponible);
	}
}
